package com.zheinfo.web.controller.wechat;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.zheinfo.common.core.controller.BaseController;
import com.zheinfo.common.core.domain.AjaxResult;
import com.zheinfo.common.core.domain.entity.SysUser;
import com.zheinfo.common.core.domain.model.LoginUser;
import com.zheinfo.common.annotation.Anonymous;
import com.zheinfo.framework.web.service.SysLoginService;
import com.zheinfo.framework.web.service.TokenService;
import com.zheinfo.system.service.ISysUserService;
import com.zheinfo.system.mapper.SysUserMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 微信授权登录Controller
 *
 * @author zheinfo
 */
@Anonymous
@RestController
@RequestMapping("/wechat/auth")
public class WechatAuthController extends BaseController
{
    private static final Logger log = LoggerFactory.getLogger(WechatAuthController.class);
    
    @Value("${wechat.appid}")
    private String appId;

    @Value("${wechat.secret}")
    private String secret;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private SysUserMapper userMapper;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private SysLoginService loginService;

    /**
     * 根据OpenID查找用户
     * 
     * @param openId 微信OpenID
     * @return 用户对象
     */
    private SysUser findUserByOpenId(String openId)
    {
        try
        {
            // 使用原生的Mapper查询，避免触发数据权限切面
            SysUser userParam = new SysUser();
            userParam.setRemark("openId:" + openId);
            
            // 使用MyBatis的Mapper直接查询，绕过数据权限检查
            List<SysUser> users = userMapper.selectUserListWithoutDataScope(userParam);
            
            if (users != null && !users.isEmpty())
            {
                return users.get(0);
            }
            
            return null;
        }
        catch (Exception e)
        {
            // 如果自定义Mapper方法不存在，回退到Service方法，但要处理权限检查异常
            log.warn("直接查询失败，尝试Service方法: {}", e.getMessage());
            
            SysUser userParam = new SysUser();
            userParam.setRemark("openId:" + openId);
            List<SysUser> users = userService.selectUserList(userParam);
            
            if (users != null && !users.isEmpty())
            {
                return users.get(0);
            }
            
            return null;
        }
    }

    /**
     * 微信小程序登录
     *
     * @param params 登录参数
     * @return 结果
     */
    @PostMapping("/login")
    public AjaxResult wechatLogin(@RequestBody Map<String, String> params)
    {
        String code = params.get("code");
        String nickName = params.get("nickName");
        String avatarUrl = params.get("avatarUrl");
        Integer gender = null;
        try {
            gender = params.get("gender") != null ? Integer.parseInt(params.get("gender")) : null;
        } catch (NumberFormatException e) {
            log.warn("解析性别参数失败: {}", params.get("gender"));
        }
        
        log.info("微信登录请求，code: {}, nickName: {}, avatarUrl: {}, gender: {}", code, nickName, avatarUrl, gender);
        
        try
        {
            // 1. 通过code获取openid和session_key
            Map<String, String> wechatResult = getOpenIdAndSessionKey(code);
            String openId = wechatResult.get("openid");
            
            if (openId == null || openId.isEmpty())
            {
                log.error("获取OpenID失败");
                return AjaxResult.error("获取用户信息失败");
            }
            
            log.info("获取到OpenID: {}", openId);
            
            // 2. 根据openId查找或创建用户
            SysUser user = findUserByOpenId(openId);
            
            if (user == null)
            {
                // 创建新用户
                log.info("创建新微信用户，openId: {}", openId);
                user = createWechatUser(openId, nickName, avatarUrl, gender);
            }
            else
            {
                // 更新用户信息（如果提供了昵称和头像）
                log.info("更新现有微信用户信息，userId: {}", user.getUserId());
                updateWechatUser(user, nickName, avatarUrl, gender);
                // 重新获取用户信息，确保数据最新
                user = userService.selectUserById(user.getUserId());
            }
            
            // 3. 执行系统登录
            Set<String> permissions = new HashSet<>();
            permissions.add("*:*:*"); // 简化处理，实际应该根据用户角色获取权限
            
            LoginUser loginUser = new LoginUser(user.getUserId(), user.getDeptId(), user, permissions);
            
            // 生成token
            String token = tokenService.createToken(loginUser);
            
            Map<String, Object> result = new HashMap<>();
            result.put("token", token);
            
            // 构建用户信息返回给前端
            Map<String, Object> userInfo = new HashMap<>();
            userInfo.put("userId", user.getUserId());
            userInfo.put("userName", user.getUserName());
            userInfo.put("nickName", user.getNickName());
            userInfo.put("avatar", user.getAvatar());
            userInfo.put("sex", user.getSex());
            result.put("userInfo", userInfo);
            
            log.info("微信登录成功，userId: {}, token: {}", user.getUserId(), token);
            return AjaxResult.success("登录成功", result);
        }
        catch (Exception e)
        {
            log.error("微信登录失败", e);
            return AjaxResult.error("登录失败: " + e.getMessage());
        }
    }

    /**
     * 通过微信code获取openid和session_key
     *
     * @param code 微信登录凭证
     * @return openid和session_key
     */
    private Map<String, String> getOpenIdAndSessionKey(String code)
    {
        try
        {
            String url = "https://api.weixin.qq.com/sns/jscode2session?appid={appid}&secret={secret}&js_code={code}&grant_type=authorization_code";
            
            Map<String, String> uriVariables = new HashMap<>();
            uriVariables.put("appid", appId);
            uriVariables.put("secret", secret);
            uriVariables.put("code", code);
            
            log.info("调用微信接口获取OpenID，URL: {}", url);
            
            RestTemplate restTemplate = new RestTemplate();
            String responseStr = restTemplate.getForObject(url, String.class, uriVariables);
            
            log.info("微信接口返回: {}", responseStr);
            
            if (responseStr != null && !responseStr.isEmpty())
            {
                // 手动解析JSON字符串，避免Content-Type问题
                JSONObject jsonObject = JSON.parseObject(responseStr);
                
                if (jsonObject.containsKey("errcode") && jsonObject.getIntValue("errcode") != 0)
                {
                    Integer errcode = jsonObject.getInteger("errcode");
                    String errmsg = jsonObject.getString("errmsg");
                    log.error("微信API返回错误，errcode: {}, errmsg: {}", errcode, errmsg);
                    throw new RuntimeException("微信接口错误(" + errcode + "): " + errmsg);
                }

                if (jsonObject.containsKey("openid"))
                {
                    // 转换为 Map
                    Map<String, String> result = new HashMap<>();
                    result.put("openid", jsonObject.getString("openid"));
                    result.put("session_key", jsonObject.getString("session_key"));
                    if (jsonObject.containsKey("unionid"))
                    {
                        result.put("unionid", jsonObject.getString("unionid"));
                    }
                    return result;
                }
                else
                {
                    log.error("微信API返回数据中没有openid，返回: {}", responseStr);
                    throw new RuntimeException("获取 OpenID 失败");
                }
            }
            else
            {
                log.error("微信API返回为null或空字符串");
                throw new RuntimeException("微信接口调用失败");
            }
        }
        catch (Exception e)
        {
            log.error("调用微信接口异常", e);
            throw new RuntimeException("调用微信接口失败：" + e.getMessage());
        }
    }

    /**
     * 创建微信用户
     *
     * @param openId 微信OpenID
     * @param nickName 昵称
     * @param avatarUrl 头像
     * @param gender 性别
     * @return 用户对象
     */
    private SysUser createWechatUser(String openId, String nickName, String avatarUrl, Integer gender)
    {
        SysUser user = new SysUser();
        user.setUserName("wx_" + openId.substring(0, Math.min(20, openId.length()))); // 生成唯一用户名
        
        // 设置昵称（确保不为空）
        if (nickName != null && !nickName.trim().isEmpty())
        {
            user.setNickName(nickName.trim());
            log.info("设置用户昵称: {}", nickName.trim());
        }
        else
        {
            user.setNickName("微信用户");
            log.warn("昵称为空，使用默认值");
        }

        // 设置头像（确保不为空）
        if (avatarUrl != null && !avatarUrl.trim().isEmpty())
        {
            user.setAvatar(avatarUrl.trim());
            log.info("设置用户头像: {}", avatarUrl.trim());
        }
        else
        {
            log.warn("头像为空，不设置头像字段");
        }

        user.setSex(gender != null ? (gender == 1 ? "0" : "1") : "2"); // 1男0女2未知
        user.setPassword("$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE/sLHSVv7"); // 微信登录默认密码（已加密）
        user.setStatus("0"); // 正常状态
        user.setDelFlag("0"); // 未删除
        user.setDeptId(103L); // 设置默认部门ID（研发部门）
        // 设置 OpenID（需要在 SysUser 中添加 openId 字段）
        user.setRemark("openId:" + openId); // 暂时存储在备注中

        try
        {
            userService.insertUser(user);
            log.info("创建微信用户成功，userName: {}, nickName: {}, avatar: {}, openId: {}", 
                     user.getUserName(), user.getNickName(), user.getAvatar(), openId);
        }
        catch (Exception e)
        {
            log.error("创建微信用户失败", e);
            throw new RuntimeException("创建用户失败：" + e.getMessage());
        }

        return user;
    }

    /**
     * 更新微信用户信息
     *
     * @param user 用户对象
     * @param nickName 昵称
     * @param avatarUrl 头像
     * @param gender 性别
     */
    private void updateWechatUser(SysUser user, String nickName, String avatarUrl, Integer gender)
    {
        boolean needUpdate = false;

        // 更新昵称
        if (nickName != null && !nickName.trim().isEmpty() && !nickName.trim().equals(user.getNickName()))
        {
            log.info("更新用户昵称: {} -> {}", user.getNickName(), nickName.trim());
            user.setNickName(nickName.trim());
            needUpdate = true;
        }

        // 更新头像
        if (avatarUrl != null && !avatarUrl.trim().isEmpty() && !avatarUrl.trim().equals(user.getAvatar()))
        {
            log.info("更新用户头像: {} -> {}", user.getAvatar(), avatarUrl.trim());
            user.setAvatar(avatarUrl.trim());
            needUpdate = true;
        }

        // 更新性别
        if (gender != null)
        {
            String sex = gender == 1 ? "0" : "1";
            if (!sex.equals(user.getSex()))
            {
                log.info("更新用户性别: {} -> {}", user.getSex(), sex);
                user.setSex(sex);
                needUpdate = true;
            }
        }

        if (needUpdate)
        {
            userService.updateUser(user);
            log.info("用户信息更新成功，userId: {}", user.getUserId());
        }
        else
        {
            log.info("用户信息无需更新，userId: {}", user.getUserId());
        }
    }
}